#include "destor.h"
#include "jcr.h"
#include "backup.h"
#include "utils/rabin_chunking.h"

static pthread_mutex_t mutex;

static pthread_t resemblance_t;

static void* resemblance_thread(void *arg) {

	while (1) {
        struct chunk* c = sync_queue_pop(rewrite_queue);

        if (c == NULL)
            /* backup job finish */
            break;

        if(CHECK_CHUNK(c, CHUNK_FILE_START) ||
        		CHECK_CHUNK(c, CHUNK_FILE_END) ||
        		CHECK_CHUNK(c, CHUNK_SEGMENT_START) ||
        		CHECK_CHUNK(c, CHUNK_SEGMENT_END)){
        	sync_queue_push(resemblance_queue, c);
        	continue;
        }

        if(CHECK_CHUNK(c, CHUNK_DUPLICATE)){
        	sync_queue_push(resemblance_queue, c);
        	continue;
        }

        if (c->size > 2048) {
            jcr.chunk_num_for_simi_dete++;
            jcr.total_size_for_similar_detection += c->size;
            
            TIMER_DECLARE(1);
            TIMER_BEGIN(1);
            if (destor.super_feature_method == SUPER_FEATURE)
                    super_feature(c->data, c->size, c->superfeature);
            else if (destor.super_feature_method == SISD_FIXED_RABIN)
                    sisd_rabin_fixed(c->data, c->size, c->superfeature);
			else if (destor.super_feature_method == SISD_FIXED_GEAR)
                    sisd_gear_fixed(c->data, c->size, c->superfeature);
            TIMER_END(1, jcr.super_feature_time);
            
        }
            
        sync_queue_push(resemblance_queue, c);
    }

    sync_queue_term(resemblance_queue);
	return NULL;
}

void start_resemblance_phase() {

	resemblance_queue = sync_queue_new(1000);
	pthread_create(&resemblance_t, NULL, resemblance_thread, NULL);
}

void stop_resemblance_phase() {
	pthread_join(resemblance_t, NULL);
}

